use ash::vk::{SurfaceKHR, SurfaceFormatKHR, PresentModeKHR, SurfaceCapabilitiesKHR, QueueFlags, DebugUtilsMessengerEXT, Image, PipelineShaderStageCreateInfo};

pub mod surface;

// Begin------------------------------------------------------------Surface
use ash::extensions::khr::Surface as KhrSurfaceFnSet;
/// handler是原生句柄
/// function_set是相关的函数调用
pub struct VkSurface {
    handler                     : SurfaceKHR,
    function_set                : KhrSurfaceFnSet
}
// End--------------------------------------------------------------Surface

// Begin------------------------------------------------------------Queue
/// Queue的类型，用于Context存储/检索目前开的Queue
/// G = Graphics  
/// T = Transision 
/// C = Compute
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub enum QueueType {
    T,
    C,
    GTC,
    COUNTER // 用于计数，放在最尾部
}
/// 辅助统计的一个临时结构<br>
/// 存放需要的Queue结构
pub struct VkRequiredQueue {
    pub queue_type              : QueueType,
    pub queue_flag              : QueueFlags,
    pub queue_count             : u32
}
/// 辅助统计的一个临时结构<br>
/// 存放Device可以提供的Queue结构
pub struct VkSupportedQueue {
    pub queue_type              : QueueType,
    pub queue_index             : u32,
    pub family_index            : u32,
    pub queue_flag              : QueueFlags,
    pub queue_priority          : f32
}
/// 辅助统计的一个临时结构<br>
/// 具体看vk_config.get_merged_family_queues
#[derive(Debug)]
pub struct VkFamilyQueue {
    pub family_index            : u32,
    pub queue_count             : u32,
    pub queue_priorities        : Vec<f32>
}
/// 存储单条Queue的信息
pub struct VkQueue {
    pub handler                 : ash::vk::Queue,
    pub queue_index             : u32,
    pub family_index            : u32,
}
/// 最后存在vk_context的结构
pub struct VkQueueMap {
    pub T_map                   : Vec<VkQueue>,
    pub C_map                   : Vec<VkQueue>,
    pub GTC_map                 : Vec<VkQueue>
}
pub mod queue;
// End--------------------------------------------------------------Queue

// Begin------------------------------------------------------------Debug Utils
use ash::extensions::ext::DebugUtils as ExtDebugUtilsFnSet;
pub struct VkDebugUtils {
    handler                     : DebugUtilsMessengerEXT,
    function_set                : ExtDebugUtilsFnSet
}
pub mod debug_utils;
// End--------------------------------------------------------------Debug Utils

// Begin------------------------------------------------------------Swapchain
use ash::vk::SwapchainKHR;
use ash::extensions::khr::Swapchain as KhrSwapchainFnSet;
pub struct VkSwapchain {
    pub handler                 : SwapchainKHR,
    pub function_set            : KhrSwapchainFnSet,
    
    pub images                  : Vec<Image>,
    pub device_support          : VkSwapchainSupport,

    pub used_format             : SurfaceFormatKHR,
    pub image_views             : Vec<ash::vk::ImageView>
}

#[derive(Debug)]
pub struct VkSwapchainSupport {
    pub surface_formats         : Vec<SurfaceFormatKHR>,
    pub surface_present_modes   : Vec<PresentModeKHR>,
    pub surface_capabilities    : SurfaceCapabilitiesKHR
}

pub mod swapchain;
// End--------------------------------------------------------------Swapchain

// Begin------------------------------------------------------------Buffer
pub mod buffer;
#[derive(Default)]
pub struct VkBuffer {
    pub handler                 : ash::vk::Buffer,
    pub memory                  : ash::vk::DeviceMemory
}
#[derive(Default)]
/// 带VkMappedMemory句柄的Buffer，可以实现映射方式的内存更新
pub struct VkMappedBuffer<T> {
    pub buffer                  : VkBuffer,
    pub mapped_handler          : Option<*mut T>
}
/// Image类似内存
/// 此时有ImageView已经有写入的能力了
/// 如果不需要读取的话，可以直接使用VkImage即可用ImageView做成FrameBuffer
#[derive(Copy, Clone, Default)]
pub struct VkImage {
    pub handler                 : ash::vk::Image,
    pub view                    : ash::vk::ImageView,
    pub memory                  : ash::vk::DeviceMemory,
    pub format                  : ash::vk::Format
}
/// 如果要在Shader里面Get，需要使用Texture
/// Texture的DescriptorImageInfo定义了Sampler与Layout的信息
#[derive(Copy, Clone, Default)]
pub struct VkTexture {
    pub handler                 : ash::vk::Image,
    pub memory                  : ash::vk::DeviceMemory,
    pub description             : ash::vk::DescriptorImageInfo,
    pub format                  : ash::vk::Format
}
// End--------------------------------------------------------------Buffer

// Begin------------------------------------------------------------Pipeline
pub mod pipeline;
pub struct VkPipelineState {
    pub vertex_input_state      : ash::vk::PipelineVertexInputStateCreateInfo,
    pub input_assembly_state    : ash::vk::PipelineInputAssemblyStateCreateInfo,
    pub tessellation_state      : ash::vk::PipelineTessellationStateCreateInfo,
    pub viewport_state          : ash::vk::PipelineViewportStateCreateInfo,
    pub rasterization_state     : ash::vk::PipelineRasterizationStateCreateInfo,
    pub multisample_state       : ash::vk::PipelineMultisampleStateCreateInfo,
    pub depth_stencil_state     : ash::vk::PipelineDepthStencilStateCreateInfo,
    pub color_blend_state       : ash::vk::PipelineColorBlendStateCreateInfo,
    pub dynamic_state           : ash::vk::PipelineDynamicStateCreateInfo
}
/// 因为Pipeline参数过于复杂，提供一个Generator取代new的时候加参数<br>
/// 这样代码更加可读，并且初始化也简化了
pub struct VkPipelineGenerator {
    pub state                               : VkPipelineState,
    pub descriptor_set_layout_count         : usize,
    pub descriptor_set_layout_generators    : Vec<VkDescriptorSetLayoutGenerator>,
    pub pipeline_shader_stage_cis           : Vec<PipelineShaderStageCreateInfo>
}
#[derive(Clone, Default)]
pub struct VkPipeline {
    pub handler                 : ash::vk::Pipeline,
    pub layout                  : ash::vk::PipelineLayout,
    pub descriptor_set_layouts  : Vec<ash::vk::DescriptorSetLayout>
}
pub struct VkDescriptorSetLayoutGenerator {
    pub layout_bindings         : Vec<ash::vk::DescriptorSetLayoutBinding>
}
pub struct VkDescriptorSet {
    pub set                     : Vec<ash::vk::DescriptorSet>,
    pub layout                  : Vec<ash::vk::DescriptorSetLayout>,
}
pub struct VkWriteDescriptorSetGenerator {
    pub write_descriptor_sets   : Vec<ash::vk::WriteDescriptorSet>,
    pub descriptor_image_infos  : Vec<ash::vk::DescriptorImageInfo>,
    pub descriptor_buffer_infos : Vec<ash::vk::DescriptorBufferInfo>
}
// End--------------------------------------------------------------Pipeline